%{

#include "stdlib.h"
void yyerror (char *);
#include "parser.h"

%}


/*
 * -- Macro Definitions
 *    -----------------
 */ 

BinaryExponent			[pP][-+]?[0-9]+
BinaryExponentIndicator	[pP]
DecimalDigit			[0-9]
Digit					[0-9]
EscapeCharacter			\\[tbnrf'"\\]
ExponentIndicator		[eE]
ExponentPart			[eE][-+]?[0-9]+
FloatTypeSuffix			[fFdD]
HexDigit				[0-9a-fA-F]
HexNumeral				0[xX][0-9a-fA-F]+
IntegerTypeSuffix		[lL]
JavaLetter				[A-Za-z_\$]
JavaLetterOrDigit		[A-Za-z_\$0-9]
NonZeroDigit			[1-9]
OctalDigit				[0-7]
Sign					[-+]
UnicodeMarker			"\\u"
UnicodeCharacter		\\u[0-9][0-9][0-9][0-9]
WhiteSpace				[ \t\f\r\n]

%x C_COMMENT

%%

{WhiteSpace}			{ }

\/\/.*					{ } 
"/*"					{ BEGIN(C_COMMENT); }
<C_COMMENT>"*/"			{ BEGIN(INITIAL); }
<C_COMMENT>.			{ }
<C_COMMENT>\n			{ }

true					{ yylval.longval = 1; return TRUE; }
false					{ yylval.longval = 0; return FALSE; }

null					{ yylval.nullval = 0; return NULLLITERAL; }

abstract				{ return ABSTRACT; }
assert					{ return ASSERT; }
boolean					{ return BOOLEAN; }
break					{ return BREAK; }
byte					{ return BYTE; }
case					{ return CASE; }
catch					{ return CATCH; }
char					{ return CHAR; }
class					{ return CLASS; }
const					{ return CONST; }
continue				{ return CONTINUE; }
default					{ return DEFAULT; }
do 						{ return DO; }
double					{ return DOUBLE; }
else 					{ return ELSE; }
enum					{ return ENUM; }
extends					{ return EXTENDS; }
final					{ return FINAL; }
finally					{ return FINALLY; }
float					{ return FLOAT; }
for 					{ return FOR; }
if 						{ return IF; }
goto					{ return GOTO; }
implements				{ return IMPLEMENTS; }
import					{ return IMPORT; }
instanceof				{ return INSTANCEOF; }
int						{ return INT; }
interface				{ return INTERFACE; }
long					{ return LONG; }
native					{ return NATIVE; }
new						{ return NEW; }
package					{ return PACKAGE; }
private					{ return PRIVATE; }
protected				{ return PROTECTED; }
public					{ return PUBLIC;}
return					{ return RETURN; }
short					{ return SHORT; }
static					{ return STATIC; }
strictfp				{ return STRICTFP; }
super					{ return SUPER; }
switch  				{ return SWITCH; }
synchronized			{ return SYNCHRONIZED; }
this					{ return THIS; }
throw					{ return THROW; }
throws					{ return THROWS; }
transient				{ return TRANSIENT; }
try 					{ return TRY; }
void					{ return VOID; }
volatile				{ return VOLATILE; }
while 					{ return WHILE; }

(0|{NonZeroDigit}{DecimalDigit}*{IntegerTypeSuffix}?)	{ return INTEGERLITERAL; } 
0[xX]{HexDigit}+{IntegerTypeSuffix}?					{ return INTEGERLITERAL; }
0{OctalDigit}+{IntegerTypeSuffix}?						{ return INTEGERLITERAL; }

{Digit}+\.{Digit}*{ExponentPart}?{FloatTypeSuffix}?		{ return FLOATINGPOINTLITERAL; }
\.{Digit}+{ExponentPart}?{FloatTypeSuffix}?				{ return FLOATINGPOINTLITERAL; }
{Digit}+{ExponentPart}{FloatTypeSuffix}?				{ return FLOATINGPOINTLITERAL; }
{Digit}+{ExponentPart}?{FloatTypeSuffix}				{ return FLOATINGPOINTLITERAL; }

{HexNumeral}(\.)?{BinaryExponent}{FloatTypeSuffix}?					{ return FLOATINGPOINTLITERAL; }
0[xX]{HexDigit}*\.{HexDigit}+{BinaryExponent}{FloatTypeSuffix}?		{ return FLOATINGPOINTLITERAL; }

\'(.|{EscapeCharacter}|{UnicodeCharacter})\'			{ 	yylval.string = strdup(yytext);
															return CHARACTERLITERAL; }
\"(\\.|[^"]|{EscapeCharacter}|{UnicodeCharacter})*\"		{ 	yylval.string = strdup(yytext);
																return STRINGLITERAL; }

\(				{ return TOK_LEFT_PAREN; }
\)				{ return TOK_RIGHT_PAREN; }
\{				{ return TOK_LEFT_BRACE; }
\}				{ return TOK_RIGHT_BRACE; }
\[				{ return TOK_LEFT_SQUARE; }
\]				{ return TOK_RIGHT_SQUARE; }
;				{ return TOK_SEMI_COLON; }
,				{ return TOK_COMMA; }
\.				{ return TOK_DOT; }
=				{ return TOK_ASSIGN; }
>				{ return TOK_GREATER_THAN; }
\<				{ return TOK_LESS_THAN; }
!				{ return TOK_EXCLAIM; }
~				{ return TOK_TILDE; }
\?				{ return TOK_QUESTION; }
:				{ return TOK_COLON; }
==				{ return TOK_EQUALS; }
\<=				{ return TOK_LESS_EQUAL; }
>=				{ return TOK_GREATER_EQUAL; }
!=				{ return TOK_NOT_EQUALS; }
&&				{ return TOK_AND_AND; }
\|\|			{ return TOK_OR_OR; }
\+\+			{ return TOK_PLUS_PLUS; }
--				{ return TOK_MINUS_MINUS; }
\+				{ return TOK_PLUS; }
-				{ return TOK_MINUS; }
\*				{ return TOK_STAR; }
\/				{ return TOK_SLASH; }
&				{ return TOK_AND; }
\|				{ return TOK_OR; }
\^				{ return TOK_XOR; }
%				{ return TOK_PERCENT; }
\<\<			{ return TOK_SHIFT_LEFT; }
>>				{ return TOK_SHIFT_RIGHT; }
>>>				{ return TOK_SHIFT_RIGHT_RIGHT; }
\+=				{ return TOK_PLUS_ASSIGN; }
-=				{ return TOK_MINUS_ASSIGN; }
\*=				{ return TOK_STAR_ASSIGN; }
\/=				{ return TOK_SLASH_ASSIGN; }
&=				{ return TOK_AND_ASSIGN; }
\|=				{ return TOK_OR_ASSIGN; }
\^=				{ return TOK_XOR_ASSIGN; }
%=				{ return TOK_PERCENT_ASSIGN; }
\<\<=			{ return TOK_SHIFT_LEFT_ASSIGN; }
>>=				{ return TOK_SHIFT_RIGHT_ASSIGN;}
>>>=			{ return TOK_SHIFT_RIGHT_RIGHT_ASSIGN; }
\.\.\.			{ return TOK_ELIPSIS; }

{JavaLetter}{JavaLetterOrDigit}*	{ 
										yylval.string = strdup(yytext); 
										return IDENTIFIER; 
									}

.				{ printf ("Invalid Character! (%c)\n", *yytext); }

%%

void yyerror (char *msg)
{
	fprintf (stderr, "%s\n", msg);
}

int yywrap(void)
{
	return 1;
}
